import Axios, {Method} from "axios"
import {AxiosOptions, RequestOptions} from './@type'
import {requestInterceptors, requestInterceptorsError, responseInterceptors, responseInterceptorsError} from "./plugin/interceptor"
import { onDownLoadProgress, onUpLoadProgress } from './plugin/progress'

/**
 * 创建默认axios服务
 */
const creatDefaultServer = (config:AxiosOptions) => {
    const { onDownload,onUpload } = config
    Axios.defaults.timeout = 600000
    Axios.defaults.headers.post['Content-Type'] = 'application/json'
    Axios.defaults.headers.patch['Content-Type'] = 'application/json'
    Axios.defaults.headers.put['Content-Type'] = 'application/json'
    Axios.defaults.timeoutErrorMessage = '请求超时'
    Axios.defaults.onDownloadProgress = ProgressEvent => onDownLoadProgress(onDownload,ProgressEvent)
    Axios.defaults.onUploadProgress = ProgressEvent => onUpLoadProgress(onUpload,ProgressEvent)
    return Axios.create()
}

/**
 * 创建请求
 * @param config
 * @param method
 */
const creatRequest =  (config:AxiosOptions,method:Method) => {
    const { api,params, server, fail, success, complete, ...otherConfig } = config
    const url = server + api // spell url
    const axios = creatDefaultServer(config) // creat New Request By Default Config
    axios.interceptors.request.use(config => requestInterceptors(<AxiosOptions>config),error => requestInterceptorsError(error,fail,complete))
    axios.interceptors.response.use( res => responseInterceptors(res,success,fail,complete) ,error => responseInterceptorsError(error,fail,complete))
    return axios.request({ method, url,params,...otherConfig }) // resolve solute
}
export class AxiosService {
    private readonly serverName:string
    constructor(serverName:string) {
        this.serverName = serverName
    }
    get = (config:RequestOptions) => creatRequest({...config,server:this.serverName},'get')
    post =  (config:RequestOptions) => creatRequest({...config,server:this.serverName},'post')
    put = (config:RequestOptions) => creatRequest({...config,server:this.serverName},'put')
    delete = (config:RequestOptions) => creatRequest({...config,server:this.serverName},'delete')
    patch = (config:RequestOptions) => creatRequest({...config,server:this.serverName},'patch')
}